//#include "stdafx.h"
#include "../../include/DirectX11/DirectX11Device.h"

namespace Adrenalin
{
	DirectX11Device::DirectX11Device()
		: _dx11SwapChain(NULL), _dx11Device(NULL), _dx11DeviceContext(NULL),
		  _dx11BackBuffer(NULL)
	{}
	// Func.: Init
	// Desc.: Initalisation of DirectX11
	void DirectX11Device::Init(HWND hWnd, int x, int y, bool windowed)
	{
		DXGI_SWAP_CHAIN_DESC scd;
		// clear out the struct for use
		ZeroMemory(&scd, sizeof(DXGI_SWAP_CHAIN_DESC));

		// fill the swap chain description struct
		scd.BufferCount = 1;                                    // one back buffer
		scd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;     // use 32-bit color
		scd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;      // how swap chain is to be used
		scd.OutputWindow = hWnd;                                // the window to be used
		scd.SampleDesc.Count = 4;                               // how many multisamples
		scd.Windowed = windowed;                                // windowed/full-screen mode

		 // create a device, device context and swap chain using the information in the scd struct
		D3D11CreateDeviceAndSwapChain(NULL,
                                  D3D_DRIVER_TYPE_HARDWARE,
                                  NULL,
                                  NULL,
                                  NULL,
                                  NULL,
                                  D3D11_SDK_VERSION,
                                  &scd,
                                  &_dx11SwapChain,
                                  &_dx11Device,
                                  NULL,
                                  &_dx11DeviceContext);

		// get the address of the back buffer
		ID3D11Texture2D *pBackBuffer;
		_dx11SwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&pBackBuffer);

		// use the back buffer address to create the render target
		_dx11Device->CreateRenderTargetView(pBackBuffer, NULL, &_dx11BackBuffer);
		pBackBuffer->Release();

		// set the render target as the back buffer
		_dx11DeviceContext->OMSetRenderTargets(1, &_dx11BackBuffer, NULL);

		// Set the viewport
		D3D11_VIEWPORT viewport;
		ZeroMemory(&viewport, sizeof(D3D11_VIEWPORT));

		viewport.TopLeftX = 0;
		viewport.TopLeftY = 0;
		viewport.Width = (float)x;
		viewport.Height = (float)y;

		_dx11DeviceContext->RSSetViewports(1, &viewport);
	}
	// Func.: Render
	// Desc.: Render a single frame
	void DirectX11Device::Render()
	{
		// clear the back buffer to a deep blue
		_dx11DeviceContext->ClearRenderTargetView(_dx11BackBuffer, D3DXCOLOR(0.0f, 0.2f, 0.4f, 1.0f));

		// do 3D rendering on the back buffer here

		// switch the back buffer and the front buffer
		_dx11SwapChain->Present(0, 0);
	}
	// Func.: Close
	// Desc.: Cleanup of all DX11 Instances
	void DirectX11Device::Close()
	{
		if(_dx11BackBuffer!=NULL)
			_dx11BackBuffer->Release();

		if(_dx11SwapChain!=NULL)
			_dx11SwapChain->Release();

		if(_dx11Device!=NULL)
			_dx11Device->Release();

		if(_dx11DeviceContext!=NULL)
			_dx11DeviceContext->Release();
	}
};